program GetWindow1;
uses
  {$ifdef unix}cthreads, {$endif} sysutils, Windows, dateutils, LazUTF8; //LCLIntf, LCLType;
(*
const
  //threadcount= 10;
  //stringlen= 1000;

  MAX_SEM_COUNT= 3;   *)
var
  //g_Semaphore: HANDLE;
  MyCriticalSection: TRTLCriticalSection;
  //finished: LongInt;
//threadvar
//  thri: PtrInt;

type
  pcom= ^consum_s;
  consum_s = record
    keyno: integer;
    iinterval: integer;
  end;

procedure time_count(interval: integer);
var
  {t1: TDateTime;}
  HH,MM,SS,MS: Word;
  HH2: Word;
begin
  {t1:= now;}

  {WriteLn('current time is [' + FormatDateTime( 'HH:MM:SS', t1) + ']');}
  DecodeTime(Time,HH,MM,SS,MS);
  Writeln (format('current time is [%.2d:%.2d:%.2d]',[HH,MM,SS]));

  if MM + interval >= 60 then
  begin
    if HH + 1 < 24 then
    begin
      HH2:= HH + 1;
      Writeln (format('[%.2d:%.2d:%.2d] would be comming',[HH2,(MM + interval)-60,SS]));
    end
    else
    begin
      HH2:= 0;
      Writeln (format('[%.2d:%.2d:%.2d] would be comming',[HH2,(MM + interval)-60,SS]));
    end;
  end
  else
    Writeln (format('[%.2d:%.2d:%.2d] would be comming',[HH,MM+interval,SS]));
  Writeln();
end;

procedure mykey_press_release(keyno: integer);
begin
  if keyno = 1 then
  begin
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(VK_1, 0, 0, 0);
    keybd_event(VK_1, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  end
  else if keyno = 2 then
  begin
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(VK_2, 0, 0, 0);
    keybd_event(VK_2, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  end
  else if keyno = 3 then
  begin
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(VK_3, 0, 0, 0);
    keybd_event(VK_3, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  end
  else if keyno = 4 then
  begin
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(VK_4, 0, 0, 0);
    keybd_event(VK_4, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  end
  else if keyno = 5 then
  begin
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(VK_5, 0, 0, 0);
    keybd_event(VK_5, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  end
  else if keyno = 6 then
  begin
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(VK_6, 0, 0, 0);
    keybd_event(VK_6, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  end
  else if keyno = 7 then
  begin
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event(VK_7, 0, 0, 0);
    keybd_event(VK_7, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
  end;
end;

procedure getContentFromClipboared(hData, phw: HWND);
begin
  OpenClipboard(phw);
  EmptyClipboard();
  SetClipboardData(CF_UNICODETEXT, hData);
  GetClipboardData(CF_UNICODETEXT);
  CloseClipboard();
  SendMessage(phw, WM_PASTE, 0, 0);
  Sleep(500);
end;

procedure get_window1(keyno, iinterval: integer);
var
  phw,hData: HWND;
  point: TPOINT;
  pData: LPWSTR;
  //i: Integer;
  //c: WideChar;
  content: WideString;
  //srcStr: LPSTR;
  //
  //disStr: LPSTR;
  //content: LPWSTR;
  //content: array[0..8] of WideChar;
  //content: string;
  //content: array[0..6] of WCHAR;
begin
  if keyno = 2 then
  begin
    content:= UTF8ToUTF16('#美滋滋');
  //lstrcpyW(PWideChar(content), PWideChar(UTF8ToUTF16('#格鲁特')));#
  end
  ELSE
  begin
  //content:=UTF8ToUTF16('#格鲁');#
  lstrcpyW(PWideChar(content), PWideChar(UTF8ToUTF16('#打卡')));
  end;
  hData:= 0;
  hData:= HWND(GlobalAlloc(GMEM_MOVEABLE, Sizeof(content)+2));
  pData:= LPWSTR(GlobalLock(hData));
  //memcpy(content, hData, Sizeof(content)+2);
  //CopyMemory(@pData, @content, Sizeof(content));
  lstrcpyW(pData, PWideChar(content));
  GlobalUnlock(hData);
  //wcscpy(@pData, @content);
  //StrLCopy(@pData, @content, Sizeof(content));

  point.x:= 1347;
  point.y:= 761;
  mykey_press_release(keyno);
  //Sleep(4000);
  time_count(iinterval);
  Sleep(1500);

  phw:= 0;
  phw:= WindowFromPoint(point);
  ShowWindow(phw, SW_SHOW);
  SetCursorPos(1347, 761);
  mouse_event(MOUSEEVENTF_LEFTDOWN, 1394, 764, 0, 0);
  mouse_event(MOUSEEVENTF_LEFTUP, 1394, 764, 0, 0);
  Sleep(1000);

  //for c in content do
  //begin
  //  SendMessage(phw,WM_CHAR, WPARAM(c), 0);
  //end;
  //if keyno = 2 then
  //begin
  //  SendMessage(phw,WM_CHAR, WPARAM('#'),0);
  //  keybd_event(VK_U, 0, 0, 0);
  //  keybd_event(VK_U, 0, KEYEVENTF_KEYUP, 0);
  //  keybd_event(VK_I, 0, 0, 0);
  //  keybd_event(VK_I, 0, KEYEVENTF_KEYUP, 0);
  //  keybd_event(VK_I, 0, 0, 0);
  //  keybd_event(VK_I, 0, KEYEVENTF_KEYUP, 0);
  //  keybd_event(VK_U, 0, 0, 0);
  //  keybd_event(VK_U, 0, KEYEVENTF_KEYUP, 0);
  //  keybd_event(VK_2, 0, 0, 0);
  //  keybd_event(VK_2, 0, KEYEVENTF_KEYUP, 0);
  //end
  //ELSE
  //begin
  //  SendMessage(phw,WM_CHAR, WPARAM('#'),0);
  //  keybd_event(VK_R, 0, 0, 0);
  //  keybd_event(VK_R, 0, KEYEVENTF_KEYUP, 0);
  //  keybd_event(VK_S, 0, 0, 0);
  //  keybd_event(VK_S, 0, KEYEVENTF_KEYUP, 0);
  //  keybd_event(VK_H, 0, 0, 0);
  //  keybd_event(VK_H, 0, KEYEVENTF_KEYUP, 0);
  //  keybd_event(VK_H, 0, 0, 0);
  //  keybd_event(VK_H, 0, KEYEVENTF_KEYUP, 0);
  //  keybd_event(VK_1, 0, 0, 0);
  //  keybd_event(VK_1, 0, KEYEVENTF_KEYUP, 0);
  //end;
  getContentFromClipboared(hData, phw);
  Sleep(500);
  keybd_event(VK_RETURN, 0, 0, 0);
  keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
  Sleep(1000);
end;

(*
function producerfun(lpParam: LPVOID): DWORD WINAPI;
//type
//  pprod= ^producer_s;
var
  count: LongInt;
  i: integer;
  //ppr: ^producer_s;
begin
  ppr:=Nil;
  ppr^:= producer_s(lpParam^);
  //pprod:= (producer_s^)lpParam;
  for i:= 0 to 1 do
  begin
    WaitForSingleObject(g_Semaphore, 0);
    WriteLn('pro-current thread name is: %d\n', GetCurrentThreadId());
    ReleaseSemaphore(g_Semaphore, 1, @count);
    Sleep(1000 * 14);
  end;

  for i:= 0 to ppr^.nums - 1 do
  begin
    Sleep(2000);
    WaitForSingleObject(g_Semaphore, 0);
    WriteLn('pro-current thread name is: %d\n', GetCurrentThreadId());
    ReleaseSemaphore(g_Semaphore, 1, @count);
    //Sleep(1000 * 60 * ppr^.iinterval);
  end;
  Result:= 0;
end;
*)

//function consumerfun(lpParam: LPVOID): DWORD WINAPI;
(* function consumerfun(lpParam: Pointer): DWORD;
//type
//  pcom= ^consum_s;
var
  count: LongInt;
  i: integer;
  pcon: ^consum_s;
begin
  pcon:=Nil;
  pcon^:= consum_s(lpParam^);
  //pconsum:= (consumer_s^)lpParam;
  for i:= 0 to pcon^.num - 1 do
  begin
    Sleep(2000);
    WaitForSingleObject(g_Semaphore, 12000);
    WriteLn('----wait for producer running----\n');
    WriteLn('cer-current thread name is: %d\n', GetCurrentThreadId());
    get_window1(pcon^.keyno, pcon^.iinterval);
    ReleaseSemaphore(g_Semaphore, 1, @count);
    Sleep(1000 * 60 * pcon^.iinterval);
  end;
  Result:= 0;
end;
*)

//function consumerfun(lpParam: LPVOID): DWORD;stdcall;
function consumerfun(lpParam: LPVOID): DWORD;stdcall;
var
  i: integer;
  pcon: ^consum_s;
begin
  pcon:=Nil;
  pcon:= pcom(lpParam);
  //try
  for i := 0 to 41 do
  begin
  Sleep(1000);
  //Writeln (format('\n[%02d:%02d:%02d] would be comming\n',[HH2,MM,SS]));
  WriteLn('----wait for producer running----');
  WriteLn(format('cer-current thread name is: %d', [GetCurrentThreadId()]));
  EnterCriticalSection(MyCriticalSection);
  // access some variables, write files, send some network packets, etc
  get_window1(pcon^.keyno, pcon^.iinterval);
  LeaveCriticalSection(MyCriticalSection);
  // RTL and LCL use same syntax, thats nice.
  Sleep(1000 * 60 * pcon^.iinterval);
  end;
  //finally
  //  LeaveCriticalSection(MyCriticalSection);
  //end;
  Result:= 0;
end;

procedure main();
var
  Tri: array[0..6] of HANDLE;
  //ThreadID: array[0..3] of DWORD;
  ThreadID: TThreadID;
  //pprod: ^producer_s;
  pconsum1,pconsum2,pconsum3,pconsum4,pconsum5,pconsum6,pconsum7: ^consum_s;
  //PPointer: pointer;
//type
//  pprodd= ^producer_s;

//type
//  pcon= ^consum_s;
//var
//  pprod: pprodd;
//  pconsum1,pconsum2: pcom;
begin
  //pprod:= Nil;
  pconsum1:= Nil;
  pconsum2:= Nil;
  pconsum3:= Nil;
  pconsum4:= Nil;
  pconsum5:= Nil;
  pconsum6:= Nil;
  pconsum7:= Nil;
  ThreadID:=0;
  //g_Semaphore:= CreateSemaphore(Nil, 0, MAX_SEM_COUNT, Nil);

  //if g_Semaphore = 0 then
  //begin
  //  WriteLn('Create Semaphore failed!: %d\n', GetLastError());
  //end;

  //pprod:= (^producer_s)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SizeOf(producer_s));

  //if pprod = Nil then
  //  WriteLn('Create producer failed!: %d\n', GetLastError());
  //end;
  //if assign(pprod) then
  //begin
  //  new (pprod);
  //end;

  //new (pprod);
  ////pprod^:= producer_s(producer_s^);
  //pprod^.nums:=40;
  //pprod^.iinterval:= 12;

  //pprod->nums:= 40;
  //pprod->iinterval:= 12;

  //pconsum1:= Nil;
  //pconsum1:= (^consum_s)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SizeOf(consum_s));
  //if pconsum1 = Nil then
  //  WriteLn('Create consumer1 failed!: %d\n', GetLastError());
  //end;
  //if assigned (pconsum1) then
  //begin
  //  new (pconsum1);
  //end;

  new (pconsum1);
  //pconsum1^.num:= 40;
  pconsum1^.keyno:= 1;
  pconsum1^.iinterval:= 20;
  //pconsum1^.name:= 1;
  //pconsum1->num:= 40;
  //pconsum1->keyno:= 1;
  //pconsum1->iinterval:= 20;
  //pconsum1->name:= 1;

  //pconsum2:= Nil;
  //pconsum2:= (^consum_s)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SizeOf(consum_s));
  //if pconsum2 = Nil then
  //  WriteLn('Create consumer2 failed!: %d\n", GetLastError());
  //end;
  //if assigned (pconsum2) then
  //begin
  //  new (pconsum2);
  //end;
  new (pconsum2);
  //pconsum2^.num:= 40;
  pconsum2^.keyno:= 2;
  pconsum2^.iinterval:= 35;
  //pconsum2^.name:= 2;
  //PPointer:= pconsum1;
  new (pconsum3);
  pconsum3^.keyno:= 3;
  pconsum3^.iinterval:= 30;

  new (pconsum4);
  pconsum4^.keyno:= 4;
  pconsum4^.iinterval:= 30;

  new (pconsum5);
  pconsum5^.keyno:= 5;
  pconsum5^.iinterval:= 30;

  new (pconsum6);
  pconsum6^.keyno:= 6;
  pconsum6^.iinterval:= 30;

  new (pconsum7);
  pconsum7^.keyno:= 7;
  pconsum7^.iinterval:= 20;

  InitCriticalSection(MyCriticalSection);
  //BeginThread(consumerfun, PPointer, ThreadID);
  //PPointer:= pconsum2;
  //BeginThread(consumerfun, PPointer, ThreadID);
  Tri[0]:= CreateThread(Nil,0,@consumerfun,pconsum1,0,ThreadID);
  Sleep(4000);
  Tri[1]:= CreateThread(Nil,0,@consumerfun,pconsum2,0,ThreadID);
  Sleep(4000);
  Tri[2]:= CreateThread(Nil,0,@consumerfun,pconsum3,0,ThreadID);
  Sleep(4000);
  Tri[3]:= CreateThread(Nil,0,@consumerfun,pconsum4,0,ThreadID);
  Sleep(4000);
  Tri[4]:= CreateThread(Nil,0,@consumerfun,pconsum5,0,ThreadID);
  Sleep(4000);
  Tri[5]:= CreateThread(Nil,0,@consumerfun,pconsum6,0,ThreadID);
  Sleep(4000);
  Tri[6]:= CreateThread(Nil,0,@consumerfun,pconsum7,0,ThreadID);
  //BeginThread(consumerfun, pconsum1);
  //BeginThread(consumerfun, pconsum2);
  //function BeginThread(ThreadFunction : tthreadfunc;p : pointer; var ThreadId : TThreadID) : TThreadID;
  //BeginThread(consumerfun,pconsum1,ThreadID);
  //BeginThread(consumerfun,pconsum2,ThreadID);

  //BeginThread(producerfun,pprod);
  //BeginThread(consumerfun,pconsum1,ThreadID[1],0);
  //BeginThread(consumerfun,pconsum2,ThreadID[2],0);
  //BeginThread(producerfun,pprod,ThreadID[0],0);
  //Tri[1] = CreateRemoteThread(0,Nil,0,@consumerfun,pconsum1,0,ThreadID[1]);
  //Tri[2] = CreateRemoteThread(0,Nil,0,@consumerfun,pconsum2,0,ThreadID[2]);
  //Tri[0] = CreateRemoteThread(0,Nil,0,@producerfun,pprod,0,ThreadID[0]);
  //external 'kernel32' name 'CreateRemoteThread';
  //Tri[1] = CreateThread(Nil,0,@consumerfun,pconsum1,0,ThreadID[1]);
  //Tri[0] = CreateThread(0, 0, consumerfun, pconsum1, 0, @ThreadID);
  //Tri[1] = CreateThread(0, 0, consumerfun, pconsum2, 0, @ThreadID);
  //Tri[0] = CreateThread(0, 0, producerfun, pprod, 0, ThreadID[0]);
  //DoneCriticalSection(MyCriticalSection);
  WaitForSingleObject(Tri[0], INFINITE);
  //WaitForSingleObject(Tri[2], INFINITE);
  WaitForSingleObject(Tri[1], INFINITE);
  WaitForSingleObject(Tri[2], INFINITE);
  WaitForSingleObject(Tri[3], INFINITE);
  WaitForSingleObject(Tri[4], INFINITE);
  WaitForSingleObject(Tri[5], INFINITE);
  WaitForSingleObject(Tri[6], INFINITE);
  DoneCriticalSection(MyCriticalSection);

  CloseHandle(Tri[0]);
  CloseHandle(Tri[1]);
  CloseHandle(Tri[2]);
  CloseHandle(Tri[3]);
  CloseHandle(Tri[4]);
  CloseHandle(Tri[5]);
  CloseHandle(Tri[6]);
  //CloseHandle(Tri[2]);
  //CloseHandle(g_Semaphore);

  //HeapFree(GetProcessHeap(), 0, pprod);
  HeapFree(GetProcessHeap(), 0, pconsum1);
  HeapFree(GetProcessHeap(), 0, pconsum2);
  HeapFree(GetProcessHeap(), 0, pconsum3);
  HeapFree(GetProcessHeap(), 0, pconsum4);
  HeapFree(GetProcessHeap(), 0, pconsum5);
  HeapFree(GetProcessHeap(), 0, pconsum6);
  HeapFree(GetProcessHeap(), 0, pconsum7);

  //FreeAndNil(pprod);
  FreeAndNil(pconsum1);
  FreeAndNil(pconsum2);
  FreeAndNil(pconsum3);
  FreeAndNil(pconsum4);
  FreeAndNil(pconsum5);
  FreeAndNil(pconsum6);
  FreeAndNil(pconsum7);
  //pprod = Nil;
  //pconsum1 = Nil;
  //pconsum2 = Nil;
  FreeAndNil(Tri);
  //FreeAndNil(ThreadID);
end;
begin
  main();

end.

